package panda.query.scan;

import static java.sql.Types.*;
import panda.query.struct.Attribute;
import panda.query.struct.Constant;
import panda.query.struct.FloatConstant;
import panda.query.struct.IntConstant;
import panda.query.struct.NullConstant;
import panda.query.struct.StringConstant;
import panda.record.RecordFile;
import panda.record.Schema;
import panda.record.TableToken;
import panda.record.TupleToken;
import panda.transaction.Transaction;

/**
 * 
 * @author Tian Yuan
 *
 */
public class TableScanner implements UpdatableScanner {

	RecordFile file;	//The iterator that reads through the file, provided by lower layers
	Schema sch;

	/**
	 * 
	 * @param tk
	 */
	public TableScanner(TableToken tk, Transaction tx) {
		file = new RecordFile(tk, tx);
		sch = tk.getSchema();
	}

	/**
	 * Set the cursor to the first tuple
	 */
	public void init() {
		file.rewind();
	}

	/**
	 * Set the cursor to the next tuple
	 * @return false if fails
	 */
	public boolean next() {
		return file.next();
	}

	/**
	 * Close the file
	 */
	public void close() {
		file.close();
	}

	/**
	 * Insert a new tuple with empty content
	 */
	public void insert() {
		file.insert();
	}

	/**
	 * Delete the tuple currently pointed to by the cursor
	 */
	public void delete() {
		file.delete();
	}

	public Constant getValue(Attribute attr) {
		String attrName = sch.getNameByAttribute(attr);

		if (file.isNull(attrName))
			return new NullConstant();

		//TODO Add other supported types
		switch (sch.getType(attr)) {
		case INTEGER :
			return new IntConstant(file.getInt(attrName));
		case CHAR : 
			return new StringConstant(file.getString(attrName));
		case FLOAT : 
			return new FloatConstant(file.getFloat(attrName));
		case VARCHAR :
			return new StringConstant(file.getString(attrName));
		case DATE :
			return new StringConstant(file.getString(attrName));
		case TIMESTAMP :
			return new StringConstant(file.getString(attrName));
		}
		return null;
	}

	public void setValue(Attribute attr, Constant value) {
		String attrName = sch.getNameByAttribute(attr);

		if (value instanceof NullConstant) file.setNull(attrName);
		// TODO Add other supported types
		switch (sch.getType(attr)) {
		case INTEGER :
			file.setInt(attrName, value.getIntValue());break;
		case VARCHAR :
			file.setString(attrName, value.getStringValue());break;
		case CHAR : 
			file.setString(attrName, value.getStringValue());break;
		case FLOAT :
			file.setFloat(attrName, value.getFloatValue());break;
		case DATE :
			file.setString(attrName, value.getStringValue());break;
		case TIMESTAMP :
			file.setString(attrName, value.getStringValue());break;
		}
	}

	public boolean hasAttribute(Attribute name) {
		return sch.hasAttribute(name);
	}

	public TupleToken getCursor() {
		return file.getCursor();
	}

	public void setCursor(TupleToken t) {
		file.setCursor(t);
	}

}
